package com.jwdemo
{
	
	// RenderHelper 
	// TODO - find out if there is anyway we can set a fixed translation to our final rendering
	// rather than adjusting the co-ordintaes for each drawing primitive! 
	
	import com.jwdemo.SpriteSheet;
	
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.external.ExternalInterface;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFormatAlign;
	import flash.text.TextLineMetrics;

	public class RenderHelper
	{
		private var gCtx: Graphics ;
		private var tmpMat:Matrix 				= 	new Matrix();
		private var indices:Vector.<int>		=	new Vector.<int>() ;		// wasteful - this only needs to built and defined once! 
		private	var mtx:Matrix 					= 	new Matrix();
		private var tRot:Number					=	0 ;
		// Simple Object format to keep RenderHelper's camera rendering offsets.
		// We have 16 overlays, in total.
		// Later - maybe - make this into a class with its own Rendering Matrix
		
		private var _overlays:Array				=	[
														{ x:0, y:0, name:"overlay0" },
														{ x:0, y:0, name:"overlay1" },
														{ x:0, y:0, name:"overlay2" },
														{ x:0, y:0, name:"overlay3" },
														{ x:0, y:0, name:"overlay4" },
														{ x:0, y:0, name:"overlay5" },
														{ x:0, y:0, name:"overlay6" },
														{ x:0, y:0, name:"overlay7" },
														{ x:0, y:0, name:"overlay8" },
														{ x:0, y:0, name:"overlay9" },
														{ x:0, y:0, name:"overlay10" },
														{ x:0, y:0, name:"overlay11" },
														{ x:0, y:0, name:"overlay12" },
														{ x:0, y:0, name:"overlay13" },
														{ x:0, y:0, name:"overlay14" },
														{ x:0, y:0, name:"overlay15" },
													] ;
		private var _overlayindex:uint			=	0 ;
		
		private var _currentoverlay:Object ;
		
		private var _dBuffer:BitmapData ;
		

		public function RenderHelper(grp:Graphics)
		{
//			_dBuffer = new BitmapData(640,420, true, 0xFF0000);

			gCtx	=	grp ;
			indices.push(0, 1, 3, 1, 2, 3);		// used for SpriteSheets
			mtx.translate(0, 0) ;				// used for SpriteSheets
			setOverlay(0) ;						// Default Overlay
		}

		public function setOverlay(overlay:uint) : void
		{
			this._overlayindex		=	overlay % this._overlays.length ;
			this._currentoverlay	=	this._overlays[this._overlayindex] ;
		}

		public function getOverlay() : uint
		{
			return 	this._overlayindex ;
		}
		
		public function camera2dSetPostition(x:int,y:int) : void
		{
			this._currentoverlay.x	=	x ;
			this._currentoverlay.y	=	y ;
		}

		
		
		public function drawRect(x:Number,y:Number,width:Number,height:Number, colour:Number) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;

			gCtx.beginFill(colour) ;
			gCtx.drawRect(x, y, width, height) ;
			gCtx.endFill() ;

		}
		
		public function drawBox( x:Number, y:Number, width:Number, height:Number, colour:Number) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
			
			gCtx.lineStyle(1,0x00000000) ;
			gCtx.drawRect(x - xt , y - yt, width, height) ;
			gCtx.endFill() ;

		}
		

		public function drawLine(x:Number, y:Number, x2:Number, y2:Number, colour:Number = 0xFF0000) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;

			gCtx.lineStyle(1, colour, .75);
			gCtx.moveTo(x - xt ,y - yt) ;
			gCtx.lineTo(x2 - xt,y2 - yt) ;
			
		}

		public function drawPoly(points:Vector.<Point>,colour:Number = 0xFF0000, cx:Number = 0, cy:Number = 0) : void
		{
			var	xt:int		=	this._currentoverlay.x - cx;
			var	yt:int 		=	this._currentoverlay.y - cy;

			gCtx.lineStyle(2, colour, 1);

			for (var idx:uint = 0 ; idx < points.length ; idx++)
			{
				gCtx.moveTo(points[idx].x - xt,points[idx].y - yt) ;
				if (idx < points.length - 1) {
					gCtx.lineTo(points[idx+1].x - xt,points[idx+1].y - yt) ;
				}
			}
			gCtx.lineTo(points[0].x - xt,points[0].y - yt) ;
		}

		public function drawCircle(x:Number, y:Number, radius:Number, colour:Number = 0xFFFF00) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;

			gCtx.beginFill(colour) ;
			gCtx.drawCircle(x - xt , y - yt, radius) ;
			gCtx.endFill() ;
			
		}
		

		// Alternative - no need for drawCircle
		
		public function drawImage(image: BitmapData, x:Number,y:Number,sx:Number = 1,sy:Number = 1, rot:Number = 0) : void
		{
			
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
	
			var vertices:Vector.<Number>	=	new Vector.<Number>() ;		

			var width:Number = image.width ;
			var height:Number = image.height ;
			
			
			

			mtx.identity() ;
			mtx.translate(-image.width/2,-image.height/2) ;
			mtx.rotate(rot*Math.PI/180.0) ;
			mtx.scale(sx,sy) ;
			mtx.translate(x - xt, y - yt) ;
			
			var p1:Point = mtx.transformPoint(new Point(0,0)) ;
			var p2:Point = mtx.transformPoint(new Point(width,0)) ;
			var p3:Point = mtx.transformPoint(new Point(width,height)) ;
			var p4:Point = mtx.transformPoint(new Point(0,height)) ;
					
		//	vertices.push(
		//		0,0,
		//		width,0,
			//	width,height,
			//	0,height);

			vertices.push(
				p1.x,p1.y,
				p2.x,p2.y,
				p3.x,p3.y,
				p4.x,p4.y);
			
			var uvData:Vector.<Number> 	= 	new Vector.<Number>() ;

			uvData.push(0,0,1,0,1,1,0,1);

			gCtx.beginBitmapFill(image,null,false,false);
			gCtx.drawTriangles(vertices,indices,uvData);
			gCtx.endFill();

			//drawCircle(x,y,10,0xFFFF00) ;
			
			
		}

		// Need to Bench mark this - probably slower than drawRect version!
		
		public function drawSheet(sheet:SpriteSheet, x:int, y:int, frame:int = 0, rot:Number = 0.0, sx:Number = 1, sy:Number = 1) : void
		{
			var	xt:int						=	this._currentoverlay.x ;
			var	yt:int 						=	this._currentoverlay.y ;
			var image:BitmapData 			=	sheet.getImage() ;

			var vertices:Vector.<Number>	=	new Vector.<Number>() ;		
			var tileWidth:uint				=	sheet.getFrameWidth() ;
			var tileHeight:uint				=	sheet.getFrameHeight() ;


			mtx.identity() ;
			mtx.translate(-tileWidth/2,-tileHeight/2) ;
			mtx.rotate(rot*Math.PI/180.0) ;
			mtx.scale(sx,sy) ;
			mtx.translate(x-xt, y-yt) ;

			
			var p1:Point = mtx.transformPoint(new Point(0,0)) ;
			var p2:Point = mtx.transformPoint(new Point(tileWidth,0)) ;
			var p3:Point = mtx.transformPoint(new Point(tileWidth,tileHeight)) ;
			var p4:Point = mtx.transformPoint(new Point(0,tileHeight)) ;
			
			
			vertices.push(
				p1.x,p1.y,
				p2.x,p2.y,
				p3.x,p3.y,
				p4.x,p4.y);
			

			gCtx.beginBitmapFill(image,null,false,false);
			gCtx.drawTriangles(vertices,indices,sheet.getUVVectorData(frame) );
			gCtx.endFill();
			
			
		}
		
		
		// Crappy Text rendering - need to know more.
		
		public function drawText(text:String, x:Number, y:Number, 
								 size:Number = 12,
								 halign:String = "left",
								 valign:String = "top",
								 inkColour:Number = 0xFFFF00,
								 paperColour:Number = 0x000000FF) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
			
			var txtfield:TextField = new TextField();
			
			var tf:TextFormat	= 	new TextFormat() ; 
			tf.align			= 	TextFormatAlign.LEFT;
			tf.bold				=	true ;
			tf.font				=	"roman" ;
			tf.size				=	size ;
			tf.color			=	inkColour ;
			tf.url				=	"http://ps3coder.com" ;
			
			txtfield.text = text ;

			txtfield.setTextFormat(tf) ;
			
			var lm:TextLineMetrics = txtfield.getLineMetrics(0) ;
			
			txtfield.width 	=	lm.width + 8 ;
			txtfield.height =	lm.height + 8 ;	// BUG IN FLASH? TEXT IS CLIPPING!

			var xadj:Number	=	(halign == "left") ? 0 : (halign == "right") ? txtfield.width : txtfield.width/2  ;
			var yadj:Number	=	(valign == "top") ? 0 : (valign == "bottom") ? txtfield.height : txtfield.height/2  ;

			
			mtx.identity() ;
			mtx.translate(-2, -2) ;

			var textImage:BitmapData = new BitmapData(txtfield.width, txtfield.height, true, paperColour);
			var ct:ColorTransform = new ColorTransform() ;
			ct.color = 0 ;
			textImage.draw(txtfield,mtx,ct,"add") ;
			textImage.draw(txtfield) ;
			
			
			mtx.identity() ;
			
			mtx.translate(x - xt - xadj, y - yt - yadj) ;
			gCtx.beginBitmapFill(textImage, mtx, false, false);
			gCtx.drawRect(x - xt - xadj, y - yt - yadj, textImage.width, textImage.height);
			gCtx.endFill();


			
		}

		public function clearContext() : void
		{
			gCtx.clear() ;

		}
		public function renderTriangles(resource:BitmapData,vertices:Vector.<Number>,indices:Vector.<int>,uvtData:Vector.<Number>, finex:Number = 0, finey:Number = 0):void 
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
			
			mtx.identity() ;
			mtx.translate(finex - xt , finey - yt) ;
			gCtx.clear() ;
			gCtx.beginBitmapFill(resource,mtx,false,false) ;
			gCtx.drawTriangles(vertices,indices,uvtData) ;
			gCtx.endFill() ;
		}
		

		
		// OLD STUFF BELOW VVVVVVVVVVVVVV
		
		// DEPRECATED - old Love2D/PS3 Home wrapper - As expected...This is SLOW!
		public function drawQuads2d(resource:BitmapData, posData:Array,uvData:Array,fineX:uint = 0, fineY:uint = 0) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;

			var tx:Number = fineX - xt ;
			var ty:Number = fineY - yt ;
			//tx = 0 ;
			//ty = 0 ;

			for (var idx:uint = 0 ; idx < posData.length ; idx++)
			{
				mtx.identity() ;
				
				var pos:Object		=	posData[idx] ;
				var uv:Object		=	uvData[idx] ;
				var	x:Number 		=	pos.xstart - tx, y:Number =	pos.ystart - ty;
				var fx:Number		=	uv.x, fy:Number	= uv.y, imgW:Number	= uv.width	, imgH:Number	=	uv.height;	
				var frm:Number		=	uv.frame ;
				mtx.translate(x - fx   ,y  - fy ) ;
				gCtx.beginBitmapFill(resource, mtx, false, false);
				gCtx.drawRect(x , y , 64, 64); //TODO
				gCtx.endFill();

			}

		}

		// DEPRECATED Need to Bench mark this - probably slower than drawRect version!
		
		public function drawSheetXX(sheet:SpriteSheet, xp:int, yp:int, frame:int = 0) : void
		{
			var	xt:int						=	this._currentoverlay.x ;
			var	yt:int 						=	this._currentoverlay.y ;
			
			var imgY:int					=	yp - yt ;			
			var imgX:int					=	xp - xt ;	
			
			var vertices:Vector.<Number>	=	new Vector.<Number>() ;		
			
			
			var tileWidth:uint				=	sheet.getFrameWidth() ;
			var tileHeight:uint				=	sheet.getFrameHeight() ;
			
			//			var rs:int 						= 	imgX	+ tileWidth ;
			
			vertices.push(
				imgX,imgY,
				imgX+tileWidth,imgY,
				imgX+tileWidth,imgY+tileHeight,
				imgX,imgY+tileHeight);
			
			
			
			
			var image:BitmapData 	=	sheet.getImage() ;
			
			mtx.identity() ;
			
			gCtx.beginBitmapFill(image,mtx,false,false);
			gCtx.drawTriangles(vertices,indices,sheet.getUVVectorData(frame) );
			gCtx.endFill();
			
			
		}
		
		// DEPRECATED
		
		public function drawImageCircleVersion(image: BitmapData, x:Number,y:Number,sx:Number = 1,sy:Number = 1, rot:Number = 0) : void
		{
			
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
			
			//TODO some savings here - static tmp Matrix
			
			
			//	var cos:Number	=	Math.cos(rot*Math.PI/180.0) ;
			//	var sin:Number	=	Math.sin(rot*Math.PI/180.0) ;
			
			//	mtx.a	=	cos ;
			//	mtx.b	=	-sin ;
			//	mtx.c	=	sin ;
			//	mtx.d	=	cos ;
			
			// TODO - Must be someway of rendering a image - other than to use a circular 'mask'
			
			var radius:Number	=	0.35*Math.sqrt(image.width*image.width*sx + image.height*image.height*sy) ;
			
			mtx.identity() ;
			mtx.translate(-image.width/2,-image.height/2) ;
			mtx.rotate(rot*Math.PI/180.0) ;
			mtx.scale(sx,sy) ;
			mtx.translate(x - xt, y - yt) ;
			
			gCtx.beginBitmapFill(image, mtx, false, false);
			gCtx.drawCircle(x - xt, y - yt, radius) ;
			gCtx.endFill();
			
			//drawCircle(x,y,radius,0xFFFF00) ;
			
			
		}
		
		// Need to find out if this beats drawTriangles - for only one frame.
		
		public function drawSheetOLD(sheet:SpriteSheet, x:Number, y:Number, frame:int = 0) : void
		{
			var	xt:int		=	this._currentoverlay.x ;
			var	yt:int 		=	this._currentoverlay.y ;
			
			var image:BitmapData 	=	sheet.getImage() ;
			var pixWid:int			=	sheet.getPixelWidth() ;
			var pixHgt:int			=	sheet.getPixelHeight() ;
			
			mtx.identity() ;
			mtx.translate(x - sheet.getFrameXOffset(frame), y - sheet.getFrameYOffset(frame)) ;
			//tmpMat.scale(1,1) ;
			//mtx.translate(x - 64, y - 0) ;
			gCtx.beginBitmapFill(image, mtx, false, false);
			gCtx.drawRect(x, y, pixWid, pixHgt);
			gCtx.endFill();
			
			
		}
		
	
	
	}
	

}